/*
 * StartApplication.java
 *
 * Created on October 8, 2006, 12:15 AM
 */

package org.sunspotworld;

import com.sun.spot.core.resources.Resources;
import com.sun.spot.core.resources.transducers.ITriColorLED;
import com.sun.spot.core.util.Utils;
import com.sun.spot.edemo.EDemoBoard;
import com.sun.spot.espot.service.BootloaderListenerService;
import com.sun.spot.ieee_802_15_4_radio.IRadioPolicyManager;
import com.sun.spot.ieee_802_15_4_radio.util.IEEEAddress;

import com.sun.spot.multihop.io.j2me.radiogram.Radiogram;
import com.sun.spot.multihop.io.j2me.radiogram.RadiogramConnection;
import java.io.*;
import javax.microedition.io.*;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

/**
 * The startApp method of this class is called by the VM to start the
 * application.
 * 
 * The manifest specifies this class as MIDlet-1, which means it will
 * be selected for execution.
 */
public class StartApplication extends MIDlet {
    private ITriColorLED [] leds = EDemoBoard.getInstance().getLEDs();
    private IRadioPolicyManager rpm = (IRadioPolicyManager)Resources.lookup(IRadioPolicyManager.class);
    private IEEEAddress ourAddr = new IEEEAddress(rpm.getIEEEAddress());

    private Thread beaconThread = new Thread() {
        public void run() {
            RadiogramConnection beacConn;
            try {
                beacConn = (RadiogramConnection) Connector.open("radiogram://broadcast:46");
                Radiogram brg = (Radiogram)beacConn.newDatagram(beacConn.getMaximumLength());
                while (true) {
                    try {
                        brg.reset();
                        brg.writeBoolean(true);
                        beacConn.send(brg);
                    } catch (IOException iOException) {
                    }
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    };
    
    protected void startApp() throws MIDletStateChangeException {
        System.out.println("Hello, world");
        BootloaderListenerService.getInstance().start();   // monitor the USB (if connected) and recognize commands from host
        RadiogramConnection conn = null;
        rpm.setOutputPower(31);  //set power to max (this is the default, but written here for completeness).  Power setting of detector is important, so that replies to both relay and sender do not get lost
        System.out.println("Our radio address = " + ourAddr.asDottedHex());
        
        Radiogram rg;
        beaconThread.start();
        leds[0].setRGB(100,0,0);                // set color to moderate red
        leds[7].setRGB(0,100,0);                // set color to moderate green
        while (true) {
            try {
                conn = (RadiogramConnection)Connector.open("radiogram://:45");
                conn.setMaxBroadcastHops(0);
                rg = (Radiogram)conn.newDatagram(conn.getMaximumLength());
                while (true) {
                    rg.reset();
                    conn.receive(rg); 
                    blinkLEDs(rg);
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            } finally {
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (IOException ex) {
                        ex.printStackTrace();
                    }
                }
            }
        }
    }
    
    private void blinkLEDs(Radiogram rg) throws IOException {
        if (rg.readLong()!=ourAddr.asLong()) {
                return;  //ignore radiograms without my address as the first long
        }
        leds[0].setOn();                    // Blink LED
        leds[7].setOn(rg.readBoolean());    // Blink LED 7 green if last message was from low-power source
        Utils.sleep(250);                   // wait 1/4 seconds
        leds[0].setOff();
        leds[7].setOff();
    }

    protected void pauseApp() {
        // This will never be called by the Squawk VM
    }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
        // Only called if startApp throws any exception other than MIDletStateChangeException
    }
}
